package ui_window;

import control.GameControl;
import ui.Img;
import util.FrameUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class JFrameConfig extends JFrame {

    private JButton btnOk = new JButton("确定");

    private JButton btnConcel = new JButton("取消");

    private JButton btnUser = new JButton("应用");

    private TextCtrl keyText[] = new TextCtrl[9];

    private JLabel errorMsg = new JLabel();

    //皮肤列表

    private JList skinList = null;

    private JPanel skinView = null;

    private DefaultListModel skinData = new DefaultListModel();


    private GameControl gameControl;

    private final static Image IMG_PSP = new ImageIcon("data/psp.jpg").getImage();

    private Image[] skinViewList = null;

    private final static String[] METHOD_NAMES = {
            "keyRight", "keyUp", "keyLeft", "keyDown",
            "keyFunLeft", "keyFunUp", "keyFunRight", "keyFunDown","keyUp2",
    };

    private final static String PATH = "data/control.dat";

    public JFrameConfig(GameControl gameControl){
        //获得游戏控制器对象
        this.gameControl = gameControl;
        //设置布局管理器为边界布局
        this.setLayout(new BorderLayout());
        this.setTitle("设置");
        //初始化按键输入框
        this.initKeyText();
        //添加主面板
        this.add(createMainPanel(),BorderLayout.CENTER);
        //添加按钮面板
        this.add(this.createButtonPanel(),BorderLayout.SOUTH);
        //设置不能改变大小
        this.setResizable(false);
        //设置窗口大小
        this.setSize(640,350);
        FrameUtil.setFrameCenter(this);
    }
    /**
     * 初始化按键输入框
     */
    private void initKeyText() {
        int x = 20;
        int y = 52;
        int w = 64;
        int h = 20;
        for(int i = 0;i < 4 ;i++){
            keyText[i] = new TextCtrl(x,y,w,h,METHOD_NAMES[i]);
            y += 28;
        }
        x = 560;
        y = 52;
        for(int i = 4;i < 9 ;i++){
            keyText[i] = new TextCtrl(x,y,w,h,METHOD_NAMES[i]);
            y += 28;
        }
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PATH));
            HashMap<Integer, String> cfgSet = (HashMap<Integer, String> )ois.readObject();
            ois.close();
            Set<Map.Entry<Integer, String>> entryset = cfgSet.entrySet();
            for (Map.Entry<Integer, String> e:entryset){
                for(TextCtrl tc: keyText){
                   if(tc.getMethodName().equals(e.getValue())){
                       tc.setKeyCode(e.getKey());
                   }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建按钮面板
     */
    private JPanel createButtonPanel() {
        //创建按钮面板，流式布局
        JPanel jp = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        //给确定按钮添加事件监听
        this.btnOk.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(writeConfig()){
                    setVisible(false);
                    gameControl.setOver();
                }
            }
        });
        //给取消按钮添加事件监听
        this.btnConcel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                gameControl.setOver();
            }
        });
        // 给应用按钮添加事件监听
        jp.add(this.btnConcel);
        this.btnUser.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                writeConfig();
                // 刷新游戏画面
                gameControl.repaint();
            }
        });
        // 设置错误信息前景色
        this.errorMsg.setForeground(Color.RED);
        jp.add(this.errorMsg);
        // 增加确定按钮到面板
        jp.add(this.btnOk);
        // 增加取消按钮到面板
        jp.add(this.btnConcel);
        jp.add(this.btnUser);
        return jp;
    }
    /**
     * 创建主面板(选项卡面板)
     */
    private JTabbedPane createMainPanel() {

        JTabbedPane jtp = new JTabbedPane();
        jtp.addTab("控制设置",this.createControlPanel());
        jtp.addTab("皮肤设置",this.createSkinPanel());
        return jtp;
    }

    /**
     * 玩家皮肤面板
     */
    private JPanel createSkinPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        // TODO 添加内容
        File dir = new File(Img.GRAPHICS_PATH);
        File[] files = dir.listFiles();
        this.skinViewList = new Image[files.length];
        for(int i = 0; i < files.length ;i++){
            //添加选项
            this.skinData.addElement(files[i].getName());
            //增加预览图
            this.skinViewList[i] = new ImageIcon(files[i].getPath() + "\\view.jpg").getImage();
        }
        // 添加列表数据到列表
        this.skinList = new JList(this.skinData);
        // 设置默认选中第一个
        this.skinList.setSelectedIndex(0);
        //添加鼠标监听
        this.skinList.addMouseListener(new MouseAdapter(){
            @Override
            public void mouseReleased(MouseEvent e) {
                repaint();
            }
        });
        this.skinView = new JPanel(){
            //皮肤预览图显示
            @Override
            public void paintComponent(Graphics g){
                Image showImg = skinViewList[skinList.getSelectedIndex()];
                int x = this.getWidth() - showImg.getWidth(null) >> 1;
                int y = this.getHeight() - showImg.getHeight(null) >> 1;
                g.drawImage(showImg,x,y,null);
            }
        };
        panel.add(new JScrollPane( this.skinList),BorderLayout.WEST);
        panel.add(this.skinView,BorderLayout.CENTER);
        return panel;
    }

    /**
     * 玩家控制设置面板
     */
    private JPanel createControlPanel() {
        JPanel jp = new JPanel(){
            @Override
            public void paintComponent(Graphics g){
                g.drawImage(IMG_PSP,0,0,null);
            }
        };
        //设置布局管理器（自油布局）
        jp.setLayout(null);
        for (int i = 0;i < keyText.length ;i++ ){
            jp.add(keyText[i]);
        }

        return jp;
    }

    /**
     *写入游戏配置
     */
    private boolean writeConfig(){
        HashMap<Integer, String> keySet = new HashMap<Integer, String>();
        for(int i = 0;i<this.keyText.length;i++) {
            int keyCode = this.keyText[i].getKeyCode();
            if (keyCode == 0){
                this.errorMsg.setText("错误按键");
                return false;
            }
            keySet.put(keyCode,this.keyText[i].getMethodName());
        }
        if(keySet.size() != 9){
            this.errorMsg.setText("重复按键");
            return false;
        }
        try {
            //切换皮肤
            Img.setSkin(this.skinData.get(this.skinList.getSelectedIndex()).toString() + "/");
            // 写入控制配置
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(PATH));
            oos.writeObject(keySet);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
            this.errorMsg.setText(e.getMessage());
            return false;
        }
        this.errorMsg.setText(null);
        return true;
    }
}
